package com.ybzl.system.controller.common;

import com.ybzl.common.core.domain.Result;
import com.ybzl.common.utils.DateUtils;
import com.ybzl.system.domain.IotData;
import com.ybzl.system.service.IotService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/iot")
public class IotController {
    @Autowired
    private IotService iotService;

    /**
     * 查询所有的盒子用于订阅
     *
     * @return
     */
    @GetMapping("/devices")
    public Result devices() {
        return Result.success(iotService.devices());
    }

    /**
     * 查询所有井
     *
     * @return
     */
    @GetMapping("/isjing")
    public Result isjing() {
        return Result.success(iotService.listjing());
    }
    /***
     *
     * @param deviceId: 盒子id
     * @param timeType 1:本日 , 2:本月 , 3:本年
     * @return
     */
    @GetMapping("/trend/v2")
    public Result queryv2(@RequestParam("deviceId") String deviceId, @RequestParam("timeType") String timeType) {
        // 根据井名称查询设备有多少指标
        List<String> indexNames = iotService.indexsByDeviceId(deviceId);
        if (ObjectUtils.isNotEmpty(indexNames)) {
            // 当天数据24小时
            if (timeType.equals("1")) {
                List<Map> rtnData = new ArrayList<>();
                for (int i = 0; i < indexNames.size(); i++) { // 遍历每一个指标
                    Map options = new HashMap();
                    // 标题区域
                    /*if (i == 0) {
                        Map titleInfo = new HashMap();
                        titleInfo.put("text", deviceId);
                        options.put("title", titleInfo);
                    }*/
                    // 当鼠标悬停时的提示属性
                    Map tooltipInfo = new HashMap();
                    tooltipInfo.put("trigger", "axis");
                    options.put("tooltip", tooltipInfo);

                    Map legend = new HashMap();
                    // 每一条线的描述
                    legend.put("data", indexNames);
                    // 配置多条线属性
                    options.put("legend", tooltipInfo);

                    // x轴描述
                    Map xAxisInfo = new HashMap();
                    xAxisInfo.put("type", "category");
                    List<Integer> hours = nhours();
                    xAxisInfo.put("data", hours);
                    xAxisInfo.put("name", "小时");
                    options.put("xAxis", xAxisInfo);

                    // y轴描述
                    Map yAxisInfo = new HashMap();
                    yAxisInfo.put("type", "value");
                    //yAxisInfo.put("name", "指标值");
                    options.put("yAxis", yAxisInfo);

                    List lists = new ArrayList();
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    //tmp.put("name", indexNames.get(i));
                    //info1.put("stack", "Total"); //该属性添加以后，只会显示每一天线的趋势，数据不会进行交叉
                    //info.put("smooth", true); // 曲线
                    // info1.put("data", data(LocalDateTime.now().getHour()));
                    List<IotData> iotData = iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.dateTimeNow("yyyy-MM-dd 00:00:00"), DateUtils.dateTimeNow("yyyy-MM-dd 23:59:59"), "hh24");

                    // 只生成当前数据，不生成未来数据，无则填充0
                    // y轴值
                    List<String> y = new ArrayList<>();
                    for (int j = 0; j <= LocalDateTime.now().getHour(); j++) {
                        boolean mzd = true;
                        for (int k = 0; k < iotData.size(); k++) {
                            // 单位
                            if(ObjectUtils.isEmpty(yAxisInfo.get("name"))){
                                yAxisInfo.put("name","单位："+iotData.get(k).getUnit());
                                // 鼠标悬停时提示名称+单位
                                tmp.put("name", indexNames.get(i)+"("+iotData.get(k).getUnit()+")");
                            }
                            if (hours.get(j) == (Integer.parseInt(iotData.get(k).getXzhou()))) {
                                y.add((String) iotData.get(k).getIndexValue());
                                mzd = false;
                                break;
                            }
                        }
                        if (mzd) {
                            y.add("0");
                        }
                    }

                    tmp.put("data", y);
                    lists.add(tmp);
                    options.put("series", lists);

                    rtnData.add(options);
                }
                // 一组数据只显示一个title
                /*for (int i = 1; i < rtnData.size(); i++) {
                    Map title = (Map) rtnData.get(1).get("title");
                    title.put("text", "");
                }*/
                return Result.success(rtnData);
            } else if (timeType.equals("2")) { // 本月的数据

                List<Map> rtnData = new ArrayList<>();
                for (int i = 0; i < indexNames.size(); i++) {
                    Map options = new HashMap();
                    // 当鼠标悬停时的提示属性
                    Map tooltipInfo = new HashMap();
                    tooltipInfo.put("trigger", "axis");
                    options.put("tooltip", tooltipInfo);

                    Map legend = new HashMap();
                    // 每一条线的描述
                    legend.put("data", indexNames);
                    // 配置多条线属性
                    options.put("legend", tooltipInfo);

                    // x轴描述
                    Map xAxisInfo = new HashMap();
                    xAxisInfo.put("type", "category");
                    List<Integer> nday = nday();
                    xAxisInfo.put("data", nday);
                    xAxisInfo.put("name", "日期");
                    options.put("xAxis", xAxisInfo);

                    // y轴描述
                    Map yAxisInfo = new HashMap();
                    yAxisInfo.put("type", "value");
                    //yAxisInfo.put("name", "指标值");
                    options.put("yAxis", yAxisInfo);

                    List lists = new ArrayList();
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    //tmp.put("name", indexNames.get(i));
                    List<IotData> iotData = iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.firtDayOfMonth(), DateUtils.lastDayOfMonth(), "dd");

                    // 处理数据：每一天的数据只取最后一条记录
                    List<IotData> tt = new ArrayList<IotData>();
                    // 去重操作
                    Map<String, String> tdata = new HashMap<>();
                    iotData.forEach(obj -> {
                        tdata.put(obj.getXzhou(), String.valueOf(obj.getIndexValue()));
                    });
                    // 重新构建返回体
                    tdata.forEach((key, value) -> {
                        IotData tmp1 = new IotData();
                        tmp1.setXzhou(key);
                        tmp1.setIndexValue(value);
                        tt.add(tmp1);
                    });

                    // 只生成当前数据，不生成未来数据，无则填充0
                    // y轴值
                    List<String> y = new ArrayList<>();
                    for (int j = 0; j < LocalDate.now().getDayOfMonth(); j++) {
                        boolean mzd = true;
                        for (int k = 0; k < tt.size(); k++) {
                            // 单位
                            if(ObjectUtils.isEmpty(yAxisInfo.get("name"))){
                                yAxisInfo.put("name","单位："+iotData.get(k).getUnit());
                                // 鼠标悬停时提示名称+单位
                                tmp.put("name", indexNames.get(i)+"("+iotData.get(k).getUnit()+")");
                            }
                            if (nday.get(j) == (Integer.parseInt(tt.get(k).getXzhou()))) {
                                y.add((String) tt.get(k).getIndexValue());
                                mzd = false;
                                break;
                            }
                        }
                        if (mzd) {
                            y.add("0");
                        }
                    }
                    tmp.put("data", y);
                    lists.add(tmp);
                    options.put("series", lists);

                    rtnData.add(options);
                }
                return Result.success(rtnData);

            } else if (timeType.equals("3")) {  // 本年的12月


                List<Map> rtnData = new ArrayList<>();
                for (int i = 0; i < indexNames.size(); i++) {
                    Map options = new HashMap();

                    // 当鼠标悬停时的提示属性
                    Map tooltipInfo = new HashMap();
                    tooltipInfo.put("trigger", "axis");
                    options.put("tooltip", tooltipInfo);

                    Map legend = new HashMap();
                    // 每一条线的描述
                    legend.put("data", indexNames);
                    // 配置多条线属性
                    options.put("legend", tooltipInfo);

                    // x轴描述
                    Map xAxisInfo = new HashMap();
                    xAxisInfo.put("type", "category");
                    List<Integer> nmonth = nmonth();
                    xAxisInfo.put("data", nmonth);
                    xAxisInfo.put("name", "月份");
                    options.put("xAxis", xAxisInfo);

                    // y轴描述
                    Map yAxisInfo = new HashMap();
                    yAxisInfo.put("type", "value");
                    //yAxisInfo.put("name", "指标值");
                    options.put("yAxis", yAxisInfo);

                    List lists = new ArrayList();
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    //tmp.put("name", indexNames.get(i));
                    List<IotData> iotData = iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.dateTimeNow("yyyy-01-01 00:00:00"), DateUtils.dateTimeNow("yyyy-12-31 23:59:59"), "mm");

                    // 处理数据：每一天的数据只取最后一条记录
                    List<IotData> tt = new ArrayList<IotData>();
                    // 去重操作
                    Map<String, String> tdata = new HashMap<>();
                    iotData.forEach(obj -> {
                        tdata.put(obj.getXzhou(), String.valueOf(obj.getIndexValue()));
                    });
                    // 重新构建返回体
                    tdata.forEach((key, value) -> {
                        IotData tmp1 = new IotData();
                        tmp1.setXzhou(key);
                        tmp1.setIndexValue(value);
                        tt.add(tmp1);
                    });

                    // 只生成当前数据，不生成未来数据，无则填充0
                    List<String> y = new ArrayList<>();
                    for (int j = 1; j <= LocalDate.now().getMonthValue(); j++) {
                        boolean mzd = true;
                        for (int k = 0; k < tt.size(); k++) {
                            // 单位
                            if(ObjectUtils.isEmpty(yAxisInfo.get("name"))){
                                yAxisInfo.put("name","单位："+iotData.get(k).getUnit());
                                // 鼠标悬停时提示名称+单位
                                tmp.put("name", indexNames.get(i)+"("+iotData.get(k).getUnit()+")");
                            }
                            if (nmonth.get(j) == (Integer.parseInt(tt.get(k).getXzhou()))) {
                                y.add((String) tt.get(k).getIndexValue());
                                mzd = false;
                                break;
                            }
                        }
                        if (mzd) {
                            y.add("0");
                        }
                    }

                    tmp.put("data", y);
                    lists.add(tmp);
                    options.put("series", lists);

                    rtnData.add(options);
                }
                return Result.success(rtnData);
            } else {
                log.info("时间类型不支持");
            }
        }
        return Result.success();
    }

    /***
     *
     * @param deviceId: 盒子id
     * @param timeType 1:本日 , 2:本月 , 3:本年
     * @return
     */
    @GetMapping("/trend/v1")
    public Map<String, Object> query(@RequestParam("deviceId") String deviceId, @RequestParam("timeType") String timeType) {
        // 根据设备Id查询设备有多少指标
        List<String> indexNames = iotService.indexsByDeviceId(deviceId);
        if (ObjectUtils.isNotEmpty(indexNames)) {
            // 当天数据24小时
            if (timeType.equals("1")) {

                Map options = new HashMap();

                // 标题区域
                Map titleInfo = new HashMap();
                titleInfo.put("text", deviceId);
                options.put("title", titleInfo);

                // 当鼠标悬停时的提示属性
                Map tooltipInfo = new HashMap();
                tooltipInfo.put("trigger", "axis");
                options.put("tooltip", tooltipInfo);

                Map legend = new HashMap();
                // 每一条线的描述
                legend.put("data", indexNames);
                // 配置多条线属性
                options.put("legend", tooltipInfo);

                // x轴描述
                Map xAxisInfo = new HashMap();
                xAxisInfo.put("type", "category");
                //xAxisInfo.put("data", nhours()); // x轴坐标数据，交由数据逻辑处生成
                xAxisInfo.put("name", "小时");
                options.put("xAxis", xAxisInfo);

                // y轴描述
                Map yAxisInfo = new HashMap();
                yAxisInfo.put("type", "value");
                yAxisInfo.put("name", "指标");
                options.put("yAxis", yAxisInfo);

                List lists = new ArrayList();
                for (int i = 0; i < indexNames.size(); i++) {
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    tmp.put("name", indexNames.get(i));
                    //info1.put("stack", "Total"); //该属性添加以后，只会显示每一天线的趋势，不会进行交叉
                    //info.put("smooth", true); // 曲线
                    // info1.put("data", data(LocalDateTime.now().getHour()));
                    List<IotData> iotData = iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.dateTimeNow("yyyy-MM-dd 00:00:00"), DateUtils.dateTimeNow("yyyy-MM-dd 23:59:59"), "hh24");
                    // x轴
                    List<String> x = new ArrayList<>();
                    List<String> y = new ArrayList<>();

                    iotData.forEach(obj -> {
                        x.add(obj.getXzhou());
                        y.add(String.valueOf(obj.getIndexValue()));
                    });

                    tmp.put("data", y);
                    if (ObjectUtils.isEmpty(xAxisInfo.get("data"))) {
                        xAxisInfo.put("data", x); // todo 多折线共用一个x轴,此处只处理一次，当多条数据的x轴试剂不一样时，可能存在显示数据出问题的情况。
                    }
                    lists.add(tmp);
                }

                // 折线数据key
                options.put("series", lists);

                return options;
            } else if (timeType.equals("2")) { // 本月的31天

                Map options = new HashMap();

                Map titleInfo = new HashMap();
                titleInfo.put("text", deviceId);
                options.put("title", titleInfo);


                Map tooltipInfo = new HashMap();
                tooltipInfo.put("trigger", "axis");
                options.put("tooltip", tooltipInfo);


                Map xAxisInfo = new HashMap();
                xAxisInfo.put("type", "category");
                //xAxisInfo.put("data", nday());  // x轴坐标数据，交由数据逻辑处生成
                xAxisInfo.put("name", "日");
                options.put("xAxis", xAxisInfo);


                Map yAxisInfo = new HashMap();
                yAxisInfo.put("type", "value");
                yAxisInfo.put("name", "指标");
                options.put("yAxis", yAxisInfo);

                List lists = new ArrayList();
                for (int i = 0; i < indexNames.size(); i++) {
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    tmp.put("name", indexNames.get(i));
                    List<IotData> iotData = iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.firtDayOfMonth(), DateUtils.lastDayOfMonth(), "dd");
                    // x轴
                    List<String> x = new ArrayList<>();
                    List<String> y = new ArrayList<>();

                    iotData.forEach(obj -> {
                        x.add(obj.getXzhou());
                        y.add(String.valueOf(obj.getIndexValue()));
                    });

                    tmp.put("data", y);
                    if (ObjectUtils.isEmpty(xAxisInfo.get("data"))) {
                        if (indexNames.get(i).equals("压力")) {
                            xAxisInfo.put("data", x); // 多折线共用一个x轴,此处只处理一次
                        }
                    }
                    lists.add(tmp);
                }

                options.put("series", lists);

                return options;

            } else if (timeType.equals("3")) {  // 本年的12月
                Map options = new HashMap();

                // 标题区域
                Map titleInfo = new HashMap();
                titleInfo.put("text", deviceId);
                options.put("title", titleInfo);

                // 当鼠标悬停时的提示属性
                Map tooltipInfo = new HashMap();
                tooltipInfo.put("trigger", "axis");
                options.put("tooltip", tooltipInfo);

                Map legend = new HashMap();
                // 每一条线的描述
                legend.put("data", indexNames);
                // 配置多条线属性
                options.put("legend", tooltipInfo);

                // x轴描述
                Map xAxisInfo = new HashMap();
                xAxisInfo.put("type", "category");
                xAxisInfo.put("data", nmonth());
                xAxisInfo.put("name", "月");
                options.put("xAxis", xAxisInfo);

                // y轴描述
                Map yAxisInfo = new HashMap();
                yAxisInfo.put("type", "value");
                yAxisInfo.put("name", "指标");
                options.put("yAxis", yAxisInfo);

                List lists = new ArrayList();
                for (int i = 0; i < indexNames.size(); i++) {
                    Map tmp = new HashMap();
                    tmp.put("type", "line");
                    tmp.put("name", indexNames.get(i));
                    //tmp.put("data", iotService.queryDeviceData(deviceId, indexNames.get(i), DateUtils.dateTimeNow("yyyy-01-01 00:00:00"), DateUtils.dateTimeNow("yyyy-12-31 23:59:59")));
                    lists.add(tmp);
                }

                // 折线数据key
                options.put("series", lists);

                return options;
            } else {
                log.info("时间类型不支持");
            }
        }
        return new HashMap<>();
    }

    /**
     * 计算当月有多少天
     *
     * @return
     */
    private List<Integer> nday() {
        List<Integer> list = new ArrayList<Integer>();
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            list.add(i);
        }
        return list;
    }

    /**
     * 生成当天24小时数据
     *
     * @return
     */
    private List<Integer> data(Integer end) {
        List<Integer> sas = new ArrayList<>();
        for (int i = 0; i < end; i++) {
            sas.add((int) (Math.random() * 10));
        }
        return sas;
    }

    /**
     * 计算当年有多少月
     *
     * @return
     */
    private List<Integer> nmonth() {
        return Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    }

    /**
     * 计算当天有多少小时
     *
     * @return
     */
    private List<Integer> nhours() {
        return Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
    }
}
